﻿#include "playerwidget.h"
#include "ui_playerwidget.h"

#include <QPainter>
#include <QMouseEvent>
#include <string>
#include <QList>
#include <QUrl>
#include <QMimeData>

#include "appsettings.h"
#include "userdatarole.h"



PlayerWidget::PlayerWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PlayerWidget),
    m_checked(),
    m_index(),
    m_isMediaEnd(true)
{
    ui->setupUi(this);

    void* hwnd = (void*)ui->widget->winId();
    m_player.reset(av::LitePlayerFactory::create(hwnd), av::LitePlayerFactory::destroy);

    m_player->setEventSink(this);

    ui->widget->setAcceptDrops(true);

}

PlayerWidget::~PlayerWidget()
{
    delete ui;
}

void PlayerWidget::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

void PlayerWidget::mousePressEvent(QMouseEvent * event)
{
    if (event->type() == QMouseEvent::MouseButtonPress)
    {
        if (event->button() == Qt::MouseButton::LeftButton)
        {
            emit clicked(m_index);
        }
        else if (event->button() == Qt::MouseButton::RightButton)
        {
            emit rclicked(m_index);
        }
    }

    QWidget::mousePressEvent(event);
}

void PlayerWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::MouseButton::LeftButton)
    {
        emit dbclicked(m_index);
    }

    QWidget::mouseDoubleClickEvent(event);
}

void PlayerWidget::dragEnterEvent(QDragEnterEvent *event)
{
    //qDebug("dragEnterEvent");

    event->acceptProposedAction();

    QWidget::dragEnterEvent(event);
}

void PlayerWidget::dragMoveEvent(QDragMoveEvent *event)
{
    QWidget::dragMoveEvent(event);
}

void PlayerWidget::dropEvent(QDropEvent *event)
{
    //qDebug("dropEvent. %d,%d", event->pos().x(), event->pos().y());

    QObject* source = event->source();
    const QMimeData* mimeData = event->mimeData();

    QList<QUrl> urls = mimeData->urls();
    QString text = mimeData->text();

    QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
    QDataStream stream(&encoded, QIODevice::ReadOnly);

    while (!stream.atEnd())
    {
        int row, col;
        QMap<int,  QVariant> roleDataMap;

        stream >> row >> col >> roleDataMap;

        QString num = roleDataMap[kNumRole].toString();
        QString name = roleDataMap[kNameRole].toString();
        QString url = roleDataMap[kUrlRole].toString();

        emit dragDropped(m_index, url, num, name);
    }

    QWidget::dropEvent(event);
}

bool PlayerWidget::checked() const
{
    return m_checked;
}

void PlayerWidget::setChecked(bool checked)
{
    m_checked = checked;

    QString style = ".PlayerWidget {";
    if (m_checked)
    {
        //style += "border: 2px solid rgb(0, 255, 0);";
    }
    else
    {
        style += "border: 1px solid rgb(150, 150, 150);";
    }

    style += "background-color: rgb(32, 32, 32);"
            "}";
    setStyleSheet(style);

}

int PlayerWidget::index() const
{
    return m_index;
}

void PlayerWidget::setIndex(int index)
{
    m_index = index;
}

bool PlayerWidget::open(const QString& filepath)
{
    if (filepath.isEmpty())
    {
        return false;
    }

	QByteArray ba = filepath.toLocal8Bit();

    m_filepath = filepath;

    std::string url = ba.data();
    int rc = m_player->open(url.c_str());
    if (rc != 0)
    {
        return false;
    }

    bool rawRatio = AppSettings::getBool("App/RawRatio", false);
    int cx = 0;
    if (!rawRatio)
    {
        cx = -1;
    }
    m_player->setRatio(cx, 0);

    m_player->play();

    m_player->setMute(true);

    m_isMediaEnd = false;

    return true;
}

void PlayerWidget::close()
{
    m_player->stop();

    m_player->close();

    m_isMediaEnd = true;
}

bool PlayerWidget::isOpen()
{
    return m_player->isOpen();
}

void PlayerWidget::pause()
{
    m_player->pause();
}

void PlayerWidget::play()
{
    m_player->play();
}

bool PlayerWidget::isPaused()
{
    return (getState() == av::STATE_PAUSED);
}

void PlayerWidget::togglePlay()
{
    m_player->togglePlay();
}

QString PlayerWidget::getFilepath() const
{
    return m_filepath;
}

int PlayerWidget::getDuration()
{
    return m_player->getDuration();
}

int PlayerWidget::getState()
{
    return m_player->getState();
}

bool PlayerWidget::seek(int offset)
{
    int rc = m_player->seek(offset);
    return (rc == 0);
}

bool PlayerWidget::seekPos(float pos)
{
    int offset = m_player->getDuration() * pos;
    return seek(offset);
}

int PlayerWidget::getTime()
{
    return (int)(m_player->getTime());
}


float PlayerWidget::getPos()
{
    int64_t curTime = m_player->getTime();
    double duration = m_player->getDuration();
    if (duration <= 0)
    {
        return 0;
    }
    return curTime / duration;
}


bool PlayerWidget::snap(const QString& filepath)
{
    m_snapFileName = filepath;

    std::string str = filepath.toStdString();
    int rc = m_player->snap(str.c_str());
    return (rc == 0);
}

void PlayerWidget::fast()
{
    float scale = m_player->getScale();
    scale = scale * 2;
    if (scale > av::MAX_SCALE)
    {
        scale = av::MAX_SCALE;
    }
    m_player->setScale(scale);
}

void PlayerWidget::slow()
{
    float scale = m_player->getScale();
    scale = scale / 2;
    if (scale < av::MIN_SCALE)
    {
        scale = av::MIN_SCALE;
    }
    m_player->setScale(scale);
}

float PlayerWidget::getScale()
{
    return m_player->getScale();
}

void PlayerWidget::onMediaEvent(av::LitePlayer* player, int type, int64_t value)
{
    qDebug("PlayerWidget::onMediaEvent. player:%p type:%d, value:%d", player, type, (int)value);

    if (type == av::MEDIA_EVENT_END)
    {
        m_isMediaEnd = true;

        emit mediaEnd(m_index);
    }
}


bool PlayerWidget::getMeta(const std::string& key, QString& value)
{
    std::string str;
    if (!m_player->getMetaData(key, str))
    {
        return false;
    }

    value = str.c_str();
    return true;
}

bool PlayerWidget::getMeta(const std::string& key, int& value)
{
	QString str;
	if (!getMeta(key, str))
	{
		return false;
	}

	value = str.toInt();
	return true;
}


bool PlayerWidget::isMediaEnd()
{
    if (!isOpen())
    {
        return true;
    }

    return m_isMediaEnd;
}
